package com.chuangjiangx.member.score.ddd.query;

import com.chuangjiangx.commons.CJBeanUtils;
import com.chuangjiangx.commons.page.PagingResult;
import com.chuangjiangx.member.score.dao.mapper.InMbrScoreGiftRecordMapper;
import com.chuangjiangx.member.score.ddd.dal.dto.*;
import com.chuangjiangx.member.score.ddd.domain.model.MbrScoreType;
import com.chuangjiangx.domain.shared.model.PayEntry;
import com.chuangjiangx.member.basic.ddd.dal.mapper.MemberDalMapper;
import com.chuangjiangx.member.score.ddd.dal.mapper.ScoreStreamDalMapper;
import com.chuangjiangx.member.score.ddd.dal.condition.QueryMbrScoreStreamCondition;
import com.chuangjiangx.member.score.ddd.dal.condition.ScoreStreamCondition;
import com.chuangjiangx.member.score.ddd.dal.condition.ScoreStreamForClientCondition;
import com.chuangjiangx.member.score.ddd.dal.condition.ScoreStreamListCondition;
import com.chuangjiangx.member.score.ddd.query.dto.*;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang.StringUtils;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * 积分明细查询
 */
@Component
public class MbrScoreStreamQuery {


    private final ScoreStreamDalMapper scoreStreamDalMapper;

    private final MemberDalMapper memberDalMapper;

    private final InMbrScoreGiftRecordMapper inMbrScoreGiftRecordMapper;

    @Autowired
    public MbrScoreStreamQuery(ScoreStreamDalMapper scoreStreamDalMapper, MemberDalMapper memberDalMapper, InMbrScoreGiftRecordMapper inMbrScoreGiftRecordMapper) {
        this.scoreStreamDalMapper = scoreStreamDalMapper;
        this.memberDalMapper = memberDalMapper;
        this.inMbrScoreGiftRecordMapper = inMbrScoreGiftRecordMapper;
    }

    /**
     * 会员积分明细列表 -商户平台
     */
    public PagingResult<PlatformDetailDTO> getPlatformDetaiList(ScoreStreamCondition condition) {

        Assert.notNull(condition.getMemberId(), "商户id不能为空");
        RowBounds rowBounds = new RowBounds(condition.offset(), condition.limit());
        Integer total = scoreStreamDalMapper.countScoreStreamList(condition);
        List<ScoreStreamList> list = new ArrayList<>();
        if(total>0){
            list = scoreStreamDalMapper.queryScoreStreamList(condition, rowBounds);
        }
        PageInfo<ScoreStreamList> pageInfo = new PageInfo<>(list);

        List<PlatformDetailDTO> platformDetailDTOList = null;
        platformDetailDTOList = CJBeanUtils.convertCollection(list, PlatformDetailDTO.class, (source, target) -> {
            if (source.getType() != null) {
                target.setTypeText(MbrScoreType.getScoreType(source.getType()).name);
            }
        });

        return new PagingResult<>(pageInfo.getPageSize(), pageInfo.getPageNum(),
                total, platformDetailDTOList);
    }

    /**
     * 当前会员积分明细列表-商户平台
     */
    public PagingResult<ScoreStreamForMerchantDTO> searchScoreStreamListForMerchant(ScoreStreamListCondition condition) {
        Assert.notNull(condition.getMemberId(), "商户id不能为空");
        Assert.notNull(condition.getMemberId(), "会员id不能为空");
        RowBounds rowBounds = new RowBounds(condition.offset(), condition.limit());
        Integer total = scoreStreamDalMapper.countScoreStreamListForMerchant(condition);
        List<ScoreStreamForMerchant> list = new ArrayList<>();
        if(total>0){
            list = scoreStreamDalMapper.queryScoreStreamListForMerchant(condition, rowBounds);
        }
        PageInfo<ScoreStreamForMerchant> pageInfo = new PageInfo<>(list);

        List<ScoreStreamForMerchantDTO> dtoList = getScoreDetailForMerchantDTOS(list);

        return new PagingResult<>(pageInfo.getPageSize(), pageInfo.getPageNum(),
                total, dtoList);
    }


    /**
     * 当前会员积分明细列表-商户平台
     */
    public List<ScoreStreamForMerchantDTO> queryScoreStreamListAll(ScoreStreamListCondition condition) {
        Assert.notNull(condition.getMemberId(), "商户id不能为空");
        Assert.notNull(condition.getMemberId(), "会员id不能为空");
        List<ScoreStreamForMerchant> list = scoreStreamDalMapper.queryScoreStreamListAll(condition);
        List<ScoreStreamForMerchantDTO> dtoList = getScoreDetailForMerchantDTOS(list);
        return dtoList;
    }

    private List<ScoreStreamForMerchantDTO> getScoreDetailForMerchantDTOS(List<ScoreStreamForMerchant> list) {
        List<ScoreStreamForMerchantDTO> dtoList = new ArrayList<>();
        list.forEach(scoreStreamForMerchant -> {
            ScoreStreamForMerchantDTO dto = new ScoreStreamForMerchantDTO(
                    scoreStreamForMerchant.getId(),
                    scoreStreamForMerchant.getCreateTime(),
                    scoreStreamForMerchant.getType(),
                    scoreStreamForMerchant.getScore(),
                    scoreStreamForMerchant.getAvailableScore(),
                    scoreStreamForMerchant.getStoreUserName());
            if (scoreStreamForMerchant.getType() != null) {
                dto.setTypeText(MbrScoreType.getScoreType(scoreStreamForMerchant.getType()).name);
            }
            dtoList.add(dto);
        });
        return dtoList;
    }


    /**
     * 收银台（APP） 积分明细列表
     */
    public PagingResult<CashierDetailDTO> getCashierDetailList(ScoreStreamCondition condition) {
        RowBounds rowBounds = new RowBounds(condition.offset(), condition.limit());
        Integer total = scoreStreamDalMapper.countScoreStreamList(condition);
        List<ScoreStreamList> list = scoreStreamDalMapper.queryScoreStreamList(condition, rowBounds);
        PageInfo<ScoreStreamList> pageInfo = new PageInfo<>(list);
        List<CashierDetailDTO> cashierDetailDTOList = new ArrayList<>();
        list.forEach(scoreDetail -> {
            CashierDetailDTO cashierDetailDTO = new CashierDetailDTO(scoreDetail.getId(), scoreDetail.getMemberCardNum(),
                    scoreDetail.getType(),
                    scoreDetail.getScore(),
                    scoreDetail.getAvailableScore(),
                    scoreDetail.getCreateTime(),
                    scoreDetail.getName(),
                    scoreDetail.getMobile());

            if (scoreDetail.getType() != null) {
                cashierDetailDTO.setTypeText(MbrScoreType.getScoreType(scoreDetail.getType()).name);
            }
            cashierDetailDTOList.add(cashierDetailDTO);
        });
        return new PagingResult<>(pageInfo.getPageSize(), pageInfo.getPageNum(),
                total, cashierDetailDTOList);
    }


    /**
     * 查询当前会员积分明细列表
     */
    public PagingResult<ClientScoreDTO> searchClientScoreDetailList(ScoreStreamForClientCondition clientCondition) {

        RowBounds rowBounds = new RowBounds(clientCondition.offset(), clientCondition.limit());
        Integer total = scoreStreamDalMapper.countScoreStreamListForClient(clientCondition);
        List<ClientScoreStreamList> list = scoreStreamDalMapper.queryScoreStreamListForClient(clientCondition, rowBounds);
        PageInfo<ClientScoreStreamList> pageInfo = new PageInfo<>(list);

        List<ClientScoreDTO> scoreDTOList = new ArrayList<>();
        list.forEach(clientScoreDetail -> {
            ClientScoreDTO clientScoreDTO = new ClientScoreDTO(
                    clientScoreDetail.getId(),
                    clientScoreDetail.getMemberCardNum(),
                    clientScoreDetail.getType(),
                    clientScoreDetail.getScore(),
                    clientScoreDetail.getAvailableScore(),
                    clientScoreDetail.getStoreId(),
                    clientScoreDetail.getStoreUserId(),
                    clientScoreDetail.getCreateTime(),
                    clientScoreDetail.getName(),
                    clientScoreDetail.getMobile(),
                    clientScoreDetail.getStoreName(),
                    clientScoreDetail.getStoreUserName()
            );
            if (clientScoreDetail.getType() != null) {
                clientScoreDTO.setTypeText(MbrScoreType.getScoreType(clientScoreDetail.getType()).name);
            }
            if (StringUtils.isBlank(clientScoreDetail.getName())) {
                switch (MbrScoreType.getScoreType(clientScoreDetail.getType())) {
                    case EXCHANGE:
                        clientScoreDTO.setName("商户主账号");
                        break;
                    case REFUND:
                        clientScoreDTO.setName("商户主账号");
                        break;
                    default:
                        clientScoreDTO.setName("当前用户");
                }
            }
            scoreDTOList.add(clientScoreDTO);
        });
        return new PagingResult<>(pageInfo.getPageSize(), pageInfo.getPageNum(),
                total, scoreDTOList);
    }

    /**
     * 商户app，H5，客户端-- 根据id查询会员消费积分详情
     */
    public AppScoreDetailDTO getScoreDetailById(Long id) {
        ClientScoreStream clientScoreStream = scoreStreamDalMapper.queryScoreStreamById(id);
        AppScoreDetailDTO appScoreDetailDTO = new AppScoreDetailDTO(
                clientScoreStream.getId(),
                clientScoreStream.getMemberCardNum(),
                clientScoreStream.getName(),
                clientScoreStream.getMobile(),
                clientScoreStream.getType(),
                clientScoreStream.getScore(),
                clientScoreStream.getAvailableScore(),
                clientScoreStream.getCreateTime(),
                clientScoreStream.getRuleName(),
                clientScoreStream.getStoreName()
        );
        if (clientScoreStream.getType() != null) {
            appScoreDetailDTO.setTypeText(MbrScoreType.getScoreType(clientScoreStream.getType()).name);
        }

        return appScoreDetailDTO;
    }

    /**
     * 根据订单号和积分类型查询 会员积分信息
     *
     * @param payOrderNum 支付单id
     * @return 返回订单积分信息
     */
    public MemberScoreInfoDTO getMemberThisTimeScoreInfo(String payOrderNum, MbrScoreType mbrScoreType) {
        MemberScoreInfo memberScoreInfo = scoreStreamDalMapper
                .getMemberThisTimeScoreInfo(payOrderNum, (int) mbrScoreType.value);
        if (memberScoreInfo == null) {
            return null;
        } else {
            MemberScoreInfoDTO info = new MemberScoreInfoDTO();
            BeanUtils.copyProperties(memberScoreInfo, info);
            return info;
        }
    }

    /**
     * 根据订单号和支付入口查询 会员积分信息
     * @param payOrderNum
     * @param payEntry
     * @return
     */
    public MemberScoreInfoDTO getMemberThisTimeScoreInfo(String payOrderNum,Integer payEntry) {
        MbrScoreType mbrScoreType = MbrScoreType.CONSUMER;
        if(!Objects.equals(PayEntry.getPayEntry(payEntry),PayEntry.MSCARDPAY)){
            mbrScoreType = MbrScoreType.OTHER_CONSUMPTION;
        }
        MemberScoreInfo memberScoreInfo = scoreStreamDalMapper
                .getMemberThisTimeScoreInfo(payOrderNum, (int) mbrScoreType.value);
        if (memberScoreInfo == null) {
            return null;
        } else {
            MemberScoreInfoDTO info = new MemberScoreInfoDTO();
            BeanUtils.copyProperties(memberScoreInfo, info);
            return info;
        }
    }

    /**
     * 根据退款单号查询会员积分信息
     *
     * @param refundOrderNum 退款单号
     * @return 返回退款单积分信息
     */
    public MemberScoreInfoDTO getRefundScoreInfoByRefundOrderNumber(String refundOrderNum) {
        MemberScoreInfo memberScoreInfo = scoreStreamDalMapper
                .queryPayScoreInfoByRefundOrderNum(refundOrderNum);

        if (memberScoreInfo == null) {
            return null;
        } else {
            MemberScoreInfoDTO info = new MemberScoreInfoDTO();
            BeanUtils.copyProperties(memberScoreInfo, info);
            return info;
        }
    }


//    /**
//     * 积分账户-积分明细
//     *
//     * @param condition 参数
//     * @return ScoreDetailForListDTO
//     */
//    public PagingResult<ScoreDetailForListDTO> queryScoreDetailForList(ScoreStreamlForListCondition condition) {
//        RowBounds rowBounds = new RowBounds(condition.offset(), condition.limit());
//        List<ScoreStreamForList> list = scoreStreamDalMapper.queryScoreStreamForList(condition, rowBounds);
//        PageInfo<ScoreStreamForList> pageInfo = new PageInfo<>(list);
//
//        List<ScoreDetailForListDTO> listDTO = CJBeanUtils.convertCollection(list, ScoreDetailForListDTO.class, (source, target) -> {
//        });
//
//        return new PagingResult<>(pageInfo.getPageNum(), pageInfo.getPageNum(), pageInfo.getTotal(), listDTO);
//    }


//    /**
//     * 积分账户-根据会员id查询积分
//     *
//     * @param condition
//     * @return ScoreValueDTO
//     */
//    public ScoreValueDTO queryScoreValueByMemberIdAndMerchant(ScoreValueCondition condition) {
//        Assert.notNull(condition.getMerchantId(), "商户id不能为空");
//        ScoreValue scoreValue = scoreStreamDalMapper.queryScoreValueByMemberIdAndMerchant(condition);
//        ScoreValueDTO scoreValueDTO = new ScoreValueDTO();
//        BeanUtils.copyProperties(scoreValueDTO, scoreValue);
//        return scoreValueDTO;
//    }

//    /**
//     * 根据订单号查询积分详情信息
//     *
//     * @param condition 参数
//     * @return list
//     */
//    public List<ScoreDetailByOrderNumDTO> queryScoreStreamByOrderNum(ScoreStreamByOrderNumCondition condition) {
//        List<ScoreStreamByOrderNum> list = scoreStreamDalMapper.queryScoreStreamByOrderNum(condition);
//        List<ScoreDetailByOrderNumDTO> listDto = CJBeanUtils.convertCollection(list, ScoreDetailByOrderNumDTO.class, (source, target) -> {
//            target.setAvailableScore(source.getAvailableScore().longValue());
//        });
//
//        return listDto;
//    }

    /**
     * 根据退款单号查询积分流水
     * @param refundNumberList
     * @return
     */
    public List<ScoreStreamDTO> queryScoreStreamWithRefundNumberList(List<String> refundNumberList){
        if(CollectionUtils.isEmpty(refundNumberList)){
            return Collections.emptyList();
        }
        return scoreStreamDalMapper.queryScoreStreamWithRefundNumberList(refundNumberList);
    }

    /**
     * 通用的查询积分流水列表可分页
     */
    public PagingResult<MbrScoreStreamList> queryMbrScoreStreamList(QueryMbrScoreStreamCondition condition){
        Integer total = scoreStreamDalMapper.countMbrScoreStreamList(condition);
        List<MbrScoreStreamList> list =  Collections.emptyList();
        if(total > 0 ){
            list = scoreStreamDalMapper.queryMbrScoreStreamList(condition);
        }
        return new PagingResult<>(total,list);
    }
}
